package com.waves.task.strategy.receive;

import cn.dev33.satoken.fun.SaFunction;
import com.alibaba.nacos.shaded.com.google.common.base.Supplier;
import com.waves.core.annotation.RedissonLock;
import com.waves.core.constant.RedisKey;
import com.waves.core.constant.redis.TaskRedisKey;
import com.waves.core.frequencycontrol.enums.CommonErrorEnum;
import com.waves.core.frequencycontrol.exception.BusinessException;
import com.waves.core.service.LockService;
import com.waves.core.utils.AssertUtil;
import com.waves.core.utils.RedisUtils;
import com.waves.core.web.domain.R;
import com.waves.task.domain.entity.Task;
import com.waves.task.domain.enums.ReceiveTypeEnum;
import org.redisson.api.RLock;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Component
public class ReceiveRLockStrategy extends AbstractReceiveStrategy {

    @Resource
    private LockService lockService;

    @Override
    ReceiveTypeEnum getReceiveTypeEnum() {
        return ReceiveTypeEnum.RECEIVE_RLOCK;
    }

    /**
     * redisson锁
     *
     * @param task
     * @return
     */
    @Override
    public R<Object> receiveTask(Task task) {
        // 查询一下任务剩余数量
        String key = RedisKey.getKey(TaskRedisKey.TASK_RECEIVE_NUM, task.getId());
        String num = RedisUtils.getStr(key);
        AssertUtil.isFalse("0".equals(num), "任务已经抢完了");

        return lockService.executeWithLock(String.valueOf(task.getId()), () -> {
            String num2 = RedisUtils.getStr(key);
            AssertUtil.isFalse("0".equals(num2), "任务已经抢完了");
            RedisUtils.decr(key);
            return super.saveTaskReceive(task);
        });
    }

    @Override
    public void cancelTask(Task task) {
        String key = RedisKey.getKey(TaskRedisKey.TASK_RECEIVE_NUM, task.getId());
        RedisUtils.incr(key);
    }

    @Override
    public void createTask(Task task) {
        String key = RedisKey.getKey(TaskRedisKey.TASK_RECEIVE_NUM, task.getId());
        Integer num = task.getBountyNum() != 0 ? task.getBountyNum() : task.getHelpBountyNum();
        RedisUtils.set(key, String.valueOf(num));

    }
}
